/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.bff.designtime.generator.core.rtgen.dataconverter.method;
import com.inspur.edp.caf.generator.baseInfo.ParameterInfo;
import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.caf.generator.method.ClassMethodGenerator;
import com.inspur.edp.cef.gencommon.MediateType;
import com.inspur.edp.cef.generator.coreGenerator.base.serializer.dataser.serializer.entity.EntityNodeDataSerGenContext;
import com.inspur.edp.cef.generator.overall.GeneratorUtil;
import com.inspur.edp.cef.generator.repository.common.IntermediateType;
import com.inspur.edp.cef.spi.jsonser.util.SerializerUtil;
import com.inspur.edp.commonmodel.spi.AbstractEntityDataSerializer;
import org.eclipse.jdt.core.dom.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;

public class GetChildConvertorGenerator extends ClassMethodGenerator {
    private EntityNodeDataSerGenContext nodeDataSerGenContext;

    public GetChildConvertorGenerator(EntityNodeDataSerGenContext nodeDataSerGenContext) {
        this.nodeDataSerGenContext = nodeDataSerGenContext;
    }

    private String paramChildCode = "childCode";
    @Override
    protected Block buildMethodBody() {
        Block block = ast.newBlock();
        buildIfStatements(block);
        buildThowExceptionStatement(block);
        return block;
    }

    private void buildThowExceptionStatement(Block block) {
        ReturnStatement returnStatement = ast.newReturnStatement();
        returnStatement.setExpression(ast.newNullLiteral());
        block.statements().add(returnStatement);
    }

    private void buildIfStatements(Block block) {
        java.util.HashMap<String, MediateType> childObjects = nodeDataSerGenContext.getChildSerTypes();
        if (childObjects == null || childObjects.size() == 0) {
            return;
        }
        for (Map.Entry<String, MediateType> childNode : childObjects.entrySet()) {
            IfStatement returnStatement = getIfStatement(childNode.getKey(), childNode.getValue());
            block.statements().add(returnStatement);
        }
    }

    private IfStatement getIfStatement(String key, MediateType objectType) {
        IfStatement ifStatement = ast.newIfStatement();
        setInfixExpression(key, ifStatement);
        setThenStatement(ifStatement, objectType);
        return ifStatement;
    }

    private void setThenStatement(IfStatement ifStatement, MediateType objectType) {
        Block block = ast.newBlock();
        ReturnStatement ifBodyReturnStatement = ast.newReturnStatement();
        ClassInstanceCreation classInstanceCreation = ast.newClassInstanceCreation();
        classInstanceCreation.setType(ast.newSimpleType(ast.newName(objectType.getClassName())));
        ifBodyReturnStatement.setExpression(classInstanceCreation);
        block.statements().add(ifBodyReturnStatement);
        ifStatement.setThenStatement(block);
    }

    private void setInfixExpression(String key, IfStatement ifStatement) {
        MethodInvocation methodInvocation=ast.newMethodInvocation();
        methodInvocation.setName(ast.newSimpleName("isChildCodeEquals"));
        methodInvocation.arguments().add(ast.newSimpleName(paramChildCode));
        StringLiteral stringLiteral=ast.newStringLiteral();
        stringLiteral.setLiteralValue(key);
        methodInvocation.arguments().add(stringLiteral);
        methodInvocation.setExpression(GeneratorUtil.buildQualifiedName(ast, SerializerUtil.class));

        ifStatement.setExpression(methodInvocation);
    }

    @Override
    protected boolean getIsOverride() {
        return true;
    }

    @Override
    protected java.util.ArrayList<Modifier.ModifierKeyword> getAccessModifiers() {
        return new java.util.ArrayList<Modifier.ModifierKeyword>(java.util.Arrays.asList(new Modifier.ModifierKeyword[]{Modifier.ModifierKeyword.PROTECTED_KEYWORD}));
    }

    @Override
    protected String getMethodName() {
        return "getChildConvertor";
    }

    //protected abstract AbstractEntityDataSerializer getChildConvertor(String var1);
    @Override
    protected ArrayList<ParameterInfo> getParameterCollection() {
        ParameterInfo parameterInfo = new ParameterInfo();
        parameterInfo.setParamName(paramChildCode);
        parameterInfo.setParamType(new TypeInfo(String.class));
        return new ArrayList<ParameterInfo>(Arrays.asList(new ParameterInfo[]{parameterInfo}));
    }

    @Override
    protected TypeInfo getReturnType() {
        return new TypeInfo(AbstractEntityDataSerializer.class);
    }
}
